﻿using System;
using __ts.Core.Api;
using log4net;

/*
 *  author: able
 *  @2012/2/20 21:49:24
 * 
 */
namespace __ts.Core.Filter.Logging
{
    public class LoggingFilter : IoFilter
    {
        /** The logger name */
        private String name;

        /** The logger */
        private ILog logger;

        /** The log level for the messageWritting event. Default to INFO. */
        private LogLevel messageWritingLevel = LogLevel.INFO;

        /** The log level for the messageReceived event. Default to INFO. */
        private LogLevel messageReceivedLevel = LogLevel.INFO;

        /** The log level for the sessionCreated event. Default to INFO. */
        private LogLevel sessionCreatedLevel = LogLevel.INFO;

        /** The log level for the sessionOpened event. Default to INFO. */
        private LogLevel sessionOpenedLevel = LogLevel.INFO;

        /** The log level for the sessionClosed event. Default to INFO. */
        private LogLevel sessionClosedLevel = LogLevel.INFO;

        /** The log level for the sessionIdle event. Default to INFO. */
        private LogLevel sessionIdleLevel = LogLevel.INFO;

        public LoggingFilter(string name)
        {
            if (name == null)
            {
                this.name = typeof(LoggingFilter).GetType().Name;
            }
            else
            {
                this.name = name;
            }

            logger = LogManager.GetLogger(this.name);
        }

        /**
     * Log if the logger and the current event log level are compatible. We log
     * a formated message and its parameters.
     * 
     * @param eventLevel the event log level as requested by the user
     * @param message the formated message to log
     * @param param the parameter injected into the message
     */
        private void log(LogLevel eventLevel, String message, Object param)
        {
            switch (eventLevel)
            {
                case LogLevel.DEBUG:
                    logger.DebugFormat(message, param);
                    return;
                case LogLevel.INFO:
                    logger.InfoFormat(message, param);
                    return;
                case LogLevel.WARN:
                    logger.WarnFormat(message, param);
                    return;
                case LogLevel.ERROR:
                    logger.ErrorFormat(message, param);
                    return;
                default:
                    return;
            }
        }

        /**
         * Log if the logger and the current event log level are compatible. We log
         * a simple message.
         * 
         * @param eventLevel the event log level as requested by the user
         * @param message the message to log
         */
        private void log(LogLevel eventLevel, String message)
        {
            switch (eventLevel)
            {
                case LogLevel.DEBUG:
                    logger.Debug(message);
                    return;
                case LogLevel.INFO:
                    logger.Info(message);
                    return;
                case LogLevel.WARN:
                    logger.Warn(message);
                    return;
                case LogLevel.ERROR:
                    logger.Error(message);
                    return;
                default:
                    return;
            }
        }


        public void sessionCreated(IoSession session)
        {
            log(sessionCreatedLevel, "CREATED");
        }

        public void sessionOpened(IoSession session)
        {
            log(sessionOpenedLevel, "OPENED");
        }

        public void sessionClosed(IoSession session)
        {
            log(sessionClosedLevel, "CLOSED");
        }

        public void sessionIdle(IoSession session, IdleStatus status)
        {
            log(sessionIdleLevel, "IDLE");
        }

        public void messageReceived(IoSession session, object message, FilterChain.ReadFilterChainController controller)
        {
            //if (message.GetType().IsInstanceOfType(  ByteBuffer)) {
            //    log(messageReceivedLevel, "RECEIVED: {}", ByteBufferDumper.dump((ByteBuffer) message));
            //} else {
            //    log(messageReceivedLevel, "RECEIVED: {}", message);
            //}

            controller.callReadNextFilter(message);
        }

        public void messageWriting(IoSession session, object message, FilterChain.WriteFilterChainController controller)
        {
            //if (message instanceof ByteBuffer) {
            //    log(messageReceivedLevel, "WRITTING: {}", ByteBufferDumper.dump((ByteBuffer) message));
            //} else {
            //    log(messageReceivedLevel, "WRITTING: {}", message);
            //}

            controller.callWriteNextFilter(message);
        }
    }
}
